#include <iostream>
#include <string>
#include <vector>
#include <netinet/in.h>//struct socket_in 结构
#include <arpa/inet.h>//字节序转换接口头文件
#include <sys/socket.h>
#include <unistd.h>

#define MAX_LISTEN 5

class TcpSocket{
  private:
    int _sockfd;
  public:
    TcpSocket()
      :_sockfd(-1)
    {}

    bool Socket()//AF_INET,SOCK_DGRAM,IPPROTO_UDP
		{
      _sockfd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
      if(_sockfd<0)
      {
        perror("socket error");
        return false;
      }
      return true;
		}
		bool Bind(const std::string &ip,uint16_t port)
		{
      struct sockaddr_in addr;
		  addr.sin_family=AF_INET;//协议族
		  addr.sin_port=htons(port);
		  addr.sin_addr.s_addr=inet_addr(ip.c_str());
		  socklen_t len=sizeof(struct sockaddr_in);
	  	int ret;
		  ret=bind(_sockfd,(struct sockaddr*)&addr,len);
		  if(ret<0)
			{
				perror("bind error");
				return false;
			}
		  return true;
		}
  bool Connect(const std::string &ip,uint16_t port)
  {
    struct sockaddr_in addr;
    addr.sin_family=AF_INET;//协议族
	  addr.sin_port=htons(port);
	  addr.sin_addr.s_addr=inet_addr(ip.c_str());
	  socklen_t len=sizeof(struct sockaddr_in);
    int ret;
    ret=connect(_sockfd,(struct sockaddr*)&addr,len);
    if(ret<0)
		{
			perror("connect error");
			return false;
		}
		return true;
  }

  bool Listen(int backlog=MAX_LISTEN)
  {
    int ret;
    ret=listen(_sockfd,backlog);
    if(ret<0)
		{
			perror("listen error");
			return false;
		}
    return true;
  }

  bool Accept(TcpSocket* sock,std::string* ip=NULL,std::string *port=NULL)
  {
    struct sockaddr_in addr;
    socklen_t len=sizeof(struct sockaddr_in);
    int new_fd;
    new_fd=accept(_sockfd,(struct sockaddr*)&addr,&len);
    if(new_fd<0)
    {
      perror("accept error");
      return false;
    }

    sock->_sockfd=new_fd;
    if(ip!=NULL)
		{
		*ip=inet_ntoa(addr.sin_addr);
		}
		if(port!=NULL)
		{
		*port=ntohs(addr.sin_port);
		}
    return true;
  }

  bool Recv(std::string *body)
  {
    char buf[3096]={0};
    int ret;
    ret=recv(_sockfd,buf,3096,0);

    if(ret<0)
    {
      perror("recv error");
      return false;
    }else if(ret==0){
      perror("recv connection disconnected");
      return false;
    }
    //*body=buf;
    body->assign(buf,ret);
    return true;
  }
  bool Send(const std::string &body)
  {
    int ret;
    ret=send(_sockfd,body.c_str(),body.size(),0);

    if(ret<0)
    {
      perror("send error");
      return false;
    }
    return true;
  }

  bool Close()
  {
    if(_sockfd!=-1)
    {
      close(_sockfd);

    }
    return true;
  }
};



